package july.framework.javautil.map;

import java.io.Serializable;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * 不定key数量Map
 */
public class SimpleMultiKeyMap<V>{

    private Map container = new HashMap();

    private ValKey valKey = new ValKey();

    public Map getContainer() {
        return container;
    }

    public boolean isEmpty() {
        return container.isEmpty();
    }

    public boolean containsKey(Object ...keys) {
        return get(keys) != null;
    }

    public V get(Object ...keys) {
        Map point = location(keys);
        if (point == null){
            return null;
        }
        Object value = point.get(valKey);
        if (value == null){
            return null;
        }
        return (V)value;
    }

    public V getOrDefault(V defaultValue, Object ...keys) {
        V r = get(keys);
        return r == null ? defaultValue : r;
    }

    public void put(V value, Object ...keys) {
        Map point = createLocation(keys);
        point.put(valKey, value);
    }

    public void putIfAbsent(V value, Object ...keys) {
        if (containsKey(keys)){
            return;
        }
        put(value, keys);
    }

    public V remove(Object ...keys) {
        Map point = location(keys);
        if (point == null){
            return null;
        }
        Object value = point.remove(valKey);
        if (value == null){
            return null;
        }
        return (V)value;
    }

    public void clear() {
        container.clear();
    }

    private Map location(Object ...keys){
        Map point = container;
        for (Object key : keys) {
            if (point.containsKey(key) && point.get(key) instanceof Map){
                point = (Map) point.get(key);
            }
            else {
                return null;
            }
        }

        return point;
    }

    private Map createLocation(Object ...keys){
        Map point = container;
        for (Object key : keys) {
            if (point.containsKey(key)){
                point = (Map) point.get(key);
            }
            else {
                point.put(key, new HashMap());
                point = (Map) point.get(key);
            }
        }

        return point;
    }

    /**
     * 值对象的key
     */
    private static class ValKey implements Serializable {
        private static final long serialVersionUID = 1L;
        private String strId = UUID.randomUUID().toString();

        @Override
        public String toString() {
            return "valKey_" + strId;
        }
    }

    /**
     * demo
     * @param args
     */
    public static void main(String[] args) {
        SimpleMultiKeyMap multiKeyMap = new SimpleMultiKeyMap();
        multiKeyMap.put("test1", 5L, "key2", 3, null);
        multiKeyMap.put("testn", 5L, "key2", 3);
        multiKeyMap.put("test2", 4L, "key2", 3);
        multiKeyMap.put("test3", 4L, "key2", null, 5L);
        multiKeyMap.put("test4", 4L, "key2", 4);
        multiKeyMap.put("test5", "k1", "k2", "k3","k4");

        System.out.println(multiKeyMap.get(5L, "key2", 3));
        System.out.println(multiKeyMap.get(5L, "key2", 3, null));
    }

}
